package com.andox.fn.inf.rpc.rest.config;

import java.util.List;
import java.util.Optional;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import com.andox.fn.inf.rpc.rest.common.Constants;
import com.andox.fn.inf.rpc.rest.util.ReflectUtil;

public class InterfaceConfig extends AbstractConfig{
	private static final long serialVersionUID = -312796328235834757L;

	private String id;
	private Class<?> interfaceClass;
	
	@OverridableProperty
	private String serialization = "kryo";	// default
	
	@OverridableProperty
	private String protocol = "restcontroller"; // default
	
	private String filter = "timeout";
	private String uniqueId;
	private Integer timeout = Constants.DEFAULT_TIMEOUT_IN_MILLISECONDS;
	private List<MethodConfig> methodConfigs;
	
	private String registry;
	
	@OverridableProperty
	private String ip;
	@OverridableProperty
	private String port;
	@OverridableProperty
	private String contextpath = "";
	
	@Override
	public void checkSelf() {
		super.checkSelf();

		Preconditions.checkArgument(this.getInterfaceClass() != null, "interfaceClass is null");
	}
	@SuppressWarnings("unchecked")
	public <T> T getConfigOfMethod(String method, String key, T defaultValue){
		Object r = null;
		Optional<MethodConfig> mc = Optional.ofNullable(methodConfigs).orElse(Lists.newArrayList()).stream().filter(e -> {return e.getName().equals(method);}).findFirst();
		if (mc.isPresent()) {
			r = ReflectUtil.findJavaProperties(mc.get(), key);
		}
		
		if (r == null) {
			r = ReflectUtil.findJavaProperties(this, key);
		}
		
		return r == null ? defaultValue : (T)r;
	}
	
	public <T> T getConfigOfMethod(String method, String key){
		return this.getConfigOfMethod(method, key, null);
	}
	
	public Class<?> getInterfaceClass() {
		return interfaceClass;
	}
	public void setInterfaceClass(Class<?> interfaceClass) {
		this.interfaceClass = interfaceClass;
	}
	public String getUniqueId() {
		return uniqueId;
	}
	public void setUniqueId(String uniqueId) {
		this.uniqueId = uniqueId;
	}
	public int getTimeout() {
		return timeout;
	}
	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}
	public List<MethodConfig> getMethodConfigs() {
		return methodConfigs;
	}
	public void setMethodConfigs(List<MethodConfig> methodConfigs) {
		this.methodConfigs = methodConfigs;
	}

	public String getSerialization() {
		return serialization;
	}

	public void setSerialization(String serialization) {
		this.serialization = serialization;
	}

	public void setTimeout(Integer timeout) {
		this.timeout = timeout;
	}

	public String getProtocol() {
		return protocol;
	}

	public void setProtocol(String protocol) {
		this.protocol = protocol;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getFilter() {
		return filter;
	}

	public void setFilter(String filter) {
		this.filter = filter;
	}

	/**
	 * @return the registry
	 */
	public String getRegistry() {
		return registry;
	}

	/**
	 * @param registry the registry to set
	 */
	public void setRegistry(String registry) {
		this.registry = registry;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getPort() {
		return port;
	}

	public void setPort(String port) {
		this.port = port;
	}

	public String getContextpath() {
		return contextpath;
	}

	public void setContextpath(String contextpath) {
		this.contextpath = contextpath;
	}
}
